﻿Imports System.Text.RegularExpressions
Imports System.Web

' Original code by "doskabouter"
' Translated to VB.NET and adapted by Xavier Flix

Public Class BrightCove
    Private video As VideoInfo
    Private url As String

    Protected Enum RequestTypes
        ViewerExperienceRequest
        FindMediaById
    End Enum

    Protected requestType As RequestTypes = RequestTypes.ViewerExperienceRequest

    Private array4 As String = ""
    Private requestUrl As String = "http://c.brightcove.com/services/messagebroker/amf"
    Private hashValue As String = ""
    Private playerCode As String
    Private videoID As String
    Private certPath As String

    Public Sub New(video As VideoInfo, url As String, videoID As String, certPath As String)
        Me.video = video
        Me.url = url
        Me.videoID = videoID
        Me.certPath = certPath
    End Sub

    Public Function GetVideoURL() As String
        playerCode = SiteUtilBase.GetWebData(url)

        Dim renditions As AMFArray
        If requestType = RequestTypes.ViewerExperienceRequest Then
            renditions = GetResultsFromViewerExperienceRequest(video)
        Else
            renditions = GetResultsFromFindByMediaId(video)
        End If

        Return FillPlaybackOptions(video, renditions)
    End Function

    Private Function GetResultsFromViewerExperienceRequest(video As VideoInfo) As AMFArray
        Dim contentOverride As AMFObject = New AMFObject("com.brightcove.experience.ContentOverride")
        Dim paramValue As String

        paramValue = videoID.ToString() ' GetParamValue("contentId")
        If paramValue <> "" Then
            Log.Debug("param contentId=" + paramValue)
            contentOverride.Add("contentId", CType(Int64.Parse(paramValue), Double))
        Else
            contentOverride.Add("contentId", Double.NaN)
        End If
        contentOverride.Add("target", "videoPlayer")

        paramValue = GetParamValue("contentRefId")
        If paramValue <> "" Then
            Log.Debug("param contentRefId=" + paramValue)
            contentOverride.Add("contentRefId", paramValue)
        Else
            contentOverride.Add("contentRefId", Nothing)
        End If

        contentOverride.Add("featuredRefId", Nothing)
        contentOverride.Add("contentRefIds", Nothing)
        contentOverride.Add("featuredId", Double.NaN)
        contentOverride.Add("contentIds", Nothing)
        contentOverride.Add("contentType", 0)
        Dim array As New AMFArray()
        array.Add(contentOverride)

        Dim ViewerExperienceRequest As AMFObject = New AMFObject("com.brightcove.experience.ViewerExperienceRequest")
        ViewerExperienceRequest.Add("TTLToken", String.Empty)
        paramValue = GetParamValue("playerKey")
        If paramValue <> "" Then
            Log.Debug("param playerKey=" + paramValue)
            ViewerExperienceRequest.Add("playerKey", paramValue)
        Else
            ViewerExperienceRequest.Add("playerKey", String.Empty)
        End If
        ViewerExperienceRequest.Add("deliveryType", Double.NaN)
        ViewerExperienceRequest.Add("contentOverrides", array)
        ViewerExperienceRequest.Add("URL", video.VideoUrl)

        paramValue = GetParamValue("experienceId")
        If paramValue <> "" Then
            Log.Debug("param experienceId=" + paramValue)
            ViewerExperienceRequest.Add("experienceId", CType(Int64.Parse(paramValue), Double))
        Else
            ViewerExperienceRequest.Add("experienceId", Double.NaN)
        End If
        Log.Debug("param URL=" + video.VideoUrl)

        paramValue = GetParamValue("playerID")
        If paramValue <> "" Then
            Log.Debug("param playerId=" + paramValue)
            ViewerExperienceRequest.Add("playerID", paramValue)
        Else
            ViewerExperienceRequest.Add("playerID", String.Empty)
        End If

        'hashValue = "61773bc7479ab4e69a5214f17fd4afd21fe1987a"

        Dim ser As AMFSerializer = New AMFSerializer()
        Dim data() As Byte = ser.Serialize(ViewerExperienceRequest, hashValue)

        Dim response As AMFObject = AMFObject.GetResponse(requestUrl, data)
        Return response.GetArray("programmedContent").GetObject("videoPlayer").GetObject("mediaDTO").GetArray("renditions")
    End Function

    Private Function GetResultsFromFindByMediaId(video As VideoInfo) As AMFArray
        Dim ser As New AMFSerializer()
        Dim values(4 - 1) As Object
        values(0) = hashValue
        values(1) = Convert.ToDouble(GetParamValue("playerID"))
        values(2) = Convert.ToDouble(GetParamValue("mediaId"))
        values(3) = Convert.ToDouble(array4)
        Dim data() As Byte = ser.Serialize2("com.brightcove.player.runtime.PlayerMediaFacade.findMediaById", values)
        Dim obj As AMFObject = AMFObject.GetResponse(requestUrl, data)
        Return obj.GetArray("renditions")
    End Function

    Private Function FillPlaybackOptions(video As VideoInfo, renditions As AMFArray) As String
        video.PlaybackOptions = New Dictionary(Of String, String)()
        For i = 0 To renditions.Count - 1
            Dim rendition As AMFObject = renditions.GetObject(i)
            Dim nm As String = String.Format("{0}x{1} {2}K",
               rendition.GetIntProperty("frameWidth"), rendition.GetIntProperty("frameHeight"),
               rendition.GetIntProperty("encodingRate") \ 1024)
            Dim url As String = HttpUtility.UrlDecode(rendition.GetStringProperty("defaultURL"))
            If url.StartsWith("rtmp") Then
                'tested with ztele
                Dim auth As String = String.Empty
                If url.Contains("?") Then auth = "?" + url.Split("?")(1)
                Dim parts = url.Split("&")

                Dim rtmp = parts(0) + auth '+ certPath
                Dim playPath = parts(1).Split("?")(0) + auth
                Dim filter = New MPUrlSourceFilter.RtmpUrl(rtmp)
                filter.PlayPath = playPath
                url = filter.ToString()
            End If
            video.PlaybackOptions.Add(nm, url)
        Next

        If video.PlaybackOptions.Count = 0 Then
            Return "" ' if no match, return empty url -> error
        Else
            If video.PlaybackOptions.Count = 1 Then
                Dim resultUrl = video.PlaybackOptions.Last().Value
                video.PlaybackOptions = Nothing ' only one url found, PlaybackOptions not needed
                Return resultUrl
            Else
                Return video.PlaybackOptions.Last().Value
            End If
        End If
    End Function

    Private Function GetParamValue(key As String) As String
        Dim p1 As Integer = playerCode.IndexOf(key)
        If p1 = -1 Then Return ""

        p1 = playerCode.IndexOf("value", p1)
        p1 = playerCode.IndexOf("""", p1) + 1
        Dim p2 = playerCode.IndexOf("""", p1 + 1)
        Return playerCode.Substring(p1, p2 - p1)
    End Function
End Class
